home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / VD08BIN.ZIP / usr / lib / site-lisp / objective-c-mode.el
Encoding:
Text File  |  1996-02-14  |  46.1 KB  |  1,390 lines

  1. ;; objective-C-mode.el
  2. ;; -------------------
  3. ;;
  4. ;; LCD Archive Entry:
  5. ;; objective-C-mode|Kenneth Persson|benneth@eb.se|
  6. ;; Major mode for editing Objective-C programs.|
  7. ;; 91-11-28|3.02|~/modes/objective-C-mode.el.Z|
  8. ;;
  9. ;; Major mode for editing Objective-C programs.
  10. ;; The Objective-C-mode is an extension of the
  11. ;; default C-mode. Unfortunately there are many
  12. ;; hardcoded parts for EB SIGNAL use only. However
  13. ;; it can be changed.  (And has: changed for RDR
  14. ;; by Chris Walters.
  15. ;;
  16. ;; Author: Kenneth Persson (kenneth@eb.se)
  17. ;;         EB Signal AB, Stockholm, Sweden
  18. ;;
  19. ;; Modified by:
  20. ;;         Douglas Worthington,
  21. ;;         dougw@grebyn.com
  22. ;;
  23. ;; Modified for use with OS/2 Objective C Libraries by:
  24. ;;         Thomas Baier
  25. ;;         baier@ci.tuwien.ac.at
  26. ;;
  27. ;; This is version 3.02.
  28. ;;
  29. ;; Put this in your .emacs file if its not in site-init.el:
  30. ;;
  31. ;; (autoload 'objective-C-mode "yourLispCodeDirectory/objective-C-mode"
  32. ;;           "Objective-C mode" t nil)
  33. ;; (setq auto-mode-alist
  34. ;;       (append '(("\\.h$" . objective-C-mode)
  35. ;;            ("\\.m$" . objective-C-mode))
  36. ;;           auto-mode-alist))
  37.  
  38. (provide 'objective-C-mode)
  39.  
  40. (defun objective-C-mode-version ()
  41.   "3.03a")
  42.  
  43. (defun echo-objective-C-mode-version ()
  44.   (interactive)
  45.   (message (concat "Version "
  46.            (objective-C-mode-version)
  47.            " of "
  48.            mode-name
  49.            " mode.")))
  50.  
  51. (defvar objective-C-interface-file-dir nil
  52.   "The directory where to put generated interface files")
  53.  
  54. (defvar objective-C-document-file-dir nil
  55.   "The directory where to put generated document files")
  56.  
  57. (defvar objective-C-mode-map nil
  58.   "*Keymap used in objective-C mode.")
  59. (if objective-C-mode-map
  60.     nil
  61.   (let ((map (make-sparse-keymap))) 
  62.     (define-key map "\C-cc"     'objective-C-mfile-header)
  63.     (define-key map "\C-ch"     'objective-C-hfile-header)   
  64.     (define-key map "\C-cp"     'objective-C-protocol)
  65.     (define-key map "\C-cf"     'objective-C-factory-method)
  66.     (define-key map "\C-cm"     'objective-C-instance-method)
  67.     (define-key map "\C-cl"     'objective-C-codelimit)
  68.     (define-key map "\C-c\C-m"  'objective-C-method-comment)
  69.     (define-key map "\C-c\C-cd" 'generate-Objective-C-documentation)
  70.     (define-key map "\C-c\C-ch" 'generate-Objective-C-hfile)   
  71.     (define-key map "\C-c?"     'describe-objective-C-mode)   
  72.     (define-key map "\C-ci"     'indent-region)
  73.     (define-key map "\C-ca"     'add-user-sign)
  74.     (define-key map "\C-cv"     'echo-objective-C-mode-version)
  75.     (define-key map "{"         'electric-objective-C-brace)
  76.     (define-key map "}"         'electric-objective-C-brace)
  77.     (define-key map ":"         'electric-objective-C-keyword-match)
  78.     (define-key map "\177"      'backward-delete-char-untabify)
  79.     (define-key map "\t"        'objective-C-indent-command)
  80.  
  81.     (define-key map [menu-bar] (make-sparse-keymap))
  82.  
  83.     (define-key map [menu-bar objective-c]
  84.       (cons "Objective-C" (make-sparse-keymap "Objective-C")))
  85.     (define-key map [menu-bar objective-c compile]
  86.       '("Compile" . compile))
  87.     (define-key map [menu-bar objective-c separator-compile] '("--"))
  88.  
  89.     (define-key map [menu-bar objective-c generate-Objective-C-documentation]
  90.       '("Generate documentation" . generate-Objective-C-documentation))
  91.     (define-key map [menu-bar objective-c generate-Objective-C-hfile]
  92.       '("Generate header file" . generate-Objective-C-hfile))
  93.     (define-key map [menu-bar objective-c separator-generate] '("--"))
  94.  
  95.     (define-key map [menu-bar objective-c objective-C-mfile-header]
  96.       '("Implementation file header" . objective-C-mfile-header))
  97.     (define-key map [menu-bar objective-c objective-C-hfile-header]
  98.       '("Interface file header" . objective-C-hfile-header))
  99.     (define-key map [menu-bar objective-c separator-headers] '("--"))
  100.  
  101.     (define-key map [menu-bar objective-c objective-C-instance-method]
  102.       '("Insert instance method" . objective-C-instance-method))
  103.     (define-key map [menu-bar objective-c objective-C-factory-method]
  104.       '("Insert factory method" . objective-C-factory-method))
  105.  
  106.     (setq objective-C-mode-map map)))
  107.  
  108. (define-abbrev-table 'objective-C-mode-abbrev-table ())
  109. (defvar objective-C-mode-abbrev-table nil
  110.   "abbrevations to use in objective-c")
  111.  
  112. ;;      (append objective-C-mode-abbrev-table
  113. ;;          (list '("ryes" "return YES"      nil)
  114. ;;            '("ry"   "return YES"      nil)
  115. ;;            '("rno"  "return NO"       nil)
  116. ;;            '("rn"   "return NO"       nil)
  117. ;;            '("rs"   "return self"     nil)
  118. ;;            '("rnil" "return nil"      nil)
  119. ;;            '("imp"  "@implementation" nil)
  120. ;;            '("intf" "@interface"      nil)
  121. ;;            '("slef" "self"            nil)
  122. ;;            '("st"   "STR"             nil)
  123. ;;            '("bo"   "BOOL"            nil))))
  124.  
  125. (defvar objective-C-mode-syntax-table nil
  126.   "Syntax table in use in Objective-C-Mode buffers.")
  127. (if objective-C-mode-syntax-table
  128.     nil
  129.   (setq objective-C-mode-syntax-table (make-syntax-table))
  130.   (modify-syntax-entry ?\\ "\\" objective-C-mode-syntax-table)
  131.   (modify-syntax-entry ?/ ". 14" objective-C-mode-syntax-table)
  132.   (modify-syntax-entry ?* ". 23" objective-C-mode-syntax-table)
  133.   (modify-syntax-entry ?+ "." objective-C-mode-syntax-table)
  134.   (modify-syntax-entry ?- "." objective-C-mode-syntax-table)
  135.   (modify-syntax-entry ?= "." objective-C-mode-syntax-table)
  136.   (modify-syntax-entry ?% "." objective-C-mode-syntax-table)
  137.   (modify-syntax-entry ?< "." objective-C-mode-syntax-table)
  138.   (modify-syntax-entry ?> "." objective-C-mode-syntax-table)
  139.   (modify-syntax-entry ?& "." objective-C-mode-syntax-table)
  140.   (modify-syntax-entry ?| "." objective-C-mode-syntax-table)
  141.   (modify-syntax-entry ?\' "\"" objective-C-mode-syntax-table))
  142.  
  143. (defconst objective-C-indent-level 2
  144.   "*Indentation of C statements with respect to containing block.")
  145. (defconst objective-C-brace-imaginary-offset 0
  146.   "*Imagined indentation of a C open brace that actually follows a statement.")
  147. (defconst objective-C-brace-offset -2
  148.   "*Extra indentation for braces, compared with other text in same context.")
  149. (defconst objective-C-argdecl-indent 3
  150.   "*Indentation level of declarations of C function arguments.")
  151. (defconst objective-C-label-offset -2
  152.   "*Offset of C label lines and case statements relative to usual indentation.")
  153. (defconst objective-C-continued-statement-offset 2
  154.   "*Extra indent for lines not starting new statements.")
  155. (defconst objective-C-auto-newline nil
  156.   "*Non-nil means automatically newline before and after braces,
  157. and after colons and semicolons, inserted in C code.")
  158. (defconst objective-C-tab-always-indent t
  159.   "*Non-nil means TAB in C mode should always reindent the current line,
  160. regardless of where in the line point is when the TAB command is used.")
  161.  
  162. (defun objective-C-mode ()
  163.   "  A major mode for the Objective-C language.
  164. Commands:
  165.   Expression and list commands understand all Objective-C brackets.
  166.   Tab anywhere on a line indents it according to Objective-C
  167.   conventions. LF does a CR and then an indentation like above.
  168.   Comments are delimited with /* ... */ or // to cr.
  169.   Paragraphs are separated by blank lines only.
  170.   Delete converts tabs to spaces as it moves back.
  171. \\{objective-C-mode-map}
  172.  
  173. Variables controlling indentation style:
  174.   objective-C-indent-level
  175.     Indentation of C statements within surrounding block.
  176.     The surrounding block's indentation is the indentation
  177.     of the line on which the open-brace appears.
  178.  
  179. Variables controlling directories of generated files:
  180.     objective-C-interface-file-dir
  181.       If non nil generated interface files will be put into
  182.       this directory. The default is current directory.
  183.     objective-C-document-file-dir
  184.       If non nil generated dokument files will be put into
  185.       this directory. The default is current directory.
  186.  
  187. Skeletons of the major Objective-C constructs are inserted with:
  188.   C-c c class header    C-c m instanceMethod     C-c f factoryMethod
  189.   C-c p protocol        C-c l limiter            C-c h header in h file
  190.   C-c <RET> method comment
  191.  
  192. Other useful stuff
  193.   C-c ? Describe objective-C mode
  194.   C-c a Add signature to use in comments
  195.   C-c v Return the version of this mode
  196.   C-c C-c h Generate an interface file from the implementation file
  197.   C-c C-c d Generate an documentation file from the implementation file
  198.  
  199. Abbreviations:
  200.   ry   & ryes  = return YES
  201.   rn   & rno   = return NO
  202.   rs   & rself = return self
  203.   rnil         = return nil
  204.   imp          = @implementation
  205.   intf         = @interface
  206.   st           = STR
  207.   bo           = BOOL
  208.  
  209. Turning on Objective-C mode calls the value of the variable
  210. objective-C-mode-hook with abbrevs, if that value is non-nil."
  211.   (interactive)
  212.   (kill-all-local-variables)
  213.   (use-local-map objective-C-mode-map)
  214.   (setq major-mode 'objective-C-mode)
  215.   (setq mode-name "Objective-C")
  216.   (setq local-abbrev-table objective-C-mode-abbrev-table)
  217.   (set-syntax-table objective-C-mode-syntax-table)
  218.   (make-local-variable 'paragraph-start)
  219.   (setq paragraph-start (concat "^$\\|" page-delimiter))
  220.   (make-local-variable 'paragraph-separate)
  221.   (setq paragraph-separate paragraph-start)
  222.   (make-local-variable 'indent-line-function)
  223.   (setq indent-line-function 'objective-C-indent-line)
  224.   (make-local-variable 'require-final-newline)
  225.   (setq require-final-newline t)
  226.   (make-local-variable 'comment-start)
  227.   (setq comment-start "/* ")
  228.   (make-local-variable 'signatures)
  229.   (setq signatures nil)
  230.   (make-local-variable 'comment-end)
  231.   (setq comment-end " */")
  232.   (make-local-variable 'comment-column)
  233.   (setq comment-column 32)
  234.   (make-local-variable 'comment-start-skip)
  235.   (setq comment-start-skip "/\\*+ *")
  236.   (make-local-variable 'comment-indent-hook)
  237.   (setq comment-indent-hook 'objective-C-comment-indent)
  238.   (make-local-variable 'parse-sexp-ignore-comments)
  239.   (setq parse-sexp-ignore-comments t)
  240.   (setq objective-C-line-length 70)
  241.   (make-local-variable 'super-filename)
  242.   (setq super-filename nil)
  243.   (run-hooks 'objective-C-mode-hook))
  244.  
  245. ;; ------------------------ EB Stuff ---------------------------
  246.  
  247. ;;--------------- site-init.el --------------- START
  248. (defun eb-day (aString)
  249.   (let ((a
  250.      (car (cdr (assoc aString '((" 1"  "01")
  251.                     (" 2"  "02")
  252.                     (" 3"  "03")
  253.                     (" 4"  "04")
  254.                     (" 5"  "05")
  255.                     (" 6"  "06")
  256.                     (" 7"  "07")
  257.                     (" 8"  "08")
  258.                     (" 9"  "09")))))))
  259.     (if (null a) aString a)))
  260.  
  261. (defun eb-month (aString)
  262.   (let ((a
  263.      (car (cdr (assoc aString '(("JAN"  "01")
  264.                     ("FEB"  "02")
  265.                     ("MAR"  "03")
  266.                     ("APR"  "04")
  267.                     ("MAY"  "05")
  268.                     ("JUN"  "06")
  269.                     ("JUL"  "07")
  270.                     ("AUG"  "08")
  271.                     ("SEP"  "09")
  272.                     ("OCT"  "10")
  273.                     ("NOV"  "11")
  274.                     ("DEC"  "12")
  275.                     ))))))
  276.     (if (null a) aString a)))
  277.  
  278. (defun eb-date ()
  279.   "Return the current date in an EB Signal standard form"
  280.   (concat (substring (current-time-string) -4 nil)
  281.       "-"
  282.       (eb-month (substring (current-time-string) 4 7))
  283.       "-"
  284.       (eb-day (substring (current-time-string) 8 10))))
  285. ;;--------------- site-init.el --------------- END
  286.  
  287. ;; ------------------ File and Class name ------------------------
  288.  
  289. ;; return the type ".m" or ".h" kan be improved
  290. (defun file-type (&optional name)
  291.   (substring (if (null name) (m-filename) name) -2 nil))
  292.  
  293. (defun m-filename ()
  294.   (file-name-nondirectory (file-name-sans-versions buffer-file-name)))
  295.  
  296. (defun is-m-file (&optional name)
  297.   (string-equal ".m" (file-type name)))
  298.  
  299. (defun h-filename ()
  300.   (concat (substring (m-filename) 0 -2) ".h"))
  301.  
  302. (defun h-file-dir ()
  303.   (if (null objective-C-interface-file-dir)
  304.       ""
  305.     objective-C-interface-file-dir))
  306.  
  307. (defun is-h-file (&optional name)
  308.   (string-equal ".h" (file-type name)))
  309.  
  310. (defun doc-filename ()
  311.   (concat (substring (m-filename) 0 -2) ".txt"))
  312.  
  313. (defun doc-dir ()
  314.   (if (null objective-C-document-file-dir)
  315.       ""
  316.     objective-C-document-file-dir))
  317.  
  318. (defun class-from-filename (&optional name)
  319.   (substring (if (null name) (m-filename) name)
  320.          0 (string-match "\\.\\([0-9]*\\.\\)?\\(m\\|h\\|txt\\)"
  321.                  (if (null name) (m-filename) name))))
  322.  
  323. (defun number-from-filename (&optional name)
  324.   (let ((m-file (if (null name) (m-filename) name)))
  325.     (substring m-file
  326.            (string-match "\\([0-9]*\\)?\\.\\(m\\|h\\)" m-file)
  327.            (- (length m-file) 2))))
  328.  
  329. ;; Tested and used. Not a very goodlooking
  330. (defun super-class ()
  331.   (let* ((row (concat "@implementation "
  332.               (class-from-filename)
  333.               "\\( \\|\t\\|\n\\)*"
  334.               ":"
  335.               "\\( \\|\t\\|\n\\)*"))
  336.      (row2 (concat row "[a-zA-Z][a-zA-Z0-9$_]*"))
  337.      (a-list (list (string-match row (buffer-string))
  338.                (match-end 0)))
  339.      (b-list (list (string-match row2 (buffer-string))
  340.                (match-end 0))))
  341.     (cond ((null (car a-list)) nil)
  342.       ((null (car b-list)) nil)
  343.       (t (buffer-substring (1+ (cadr a-list))
  344.                    (1+ (cadr b-list)))))))
  345.  
  346. (defun super-class-number ()
  347.   (let ((sc (super-class))
  348.     (no nil))
  349.     (if (null sc) "NO_SUPER_CLASS_FOUND"
  350.       (setq no (read-string (concat "Class number for superclass "
  351.                     (super-class)
  352.                     ": ")))
  353.       (if (string-equal "" no) no
  354.     (concat "." no)))))
  355.  
  356. (defun super-hfilename (&optional number)
  357.   (let ((sc (super-class))
  358.     (no (if (null number) (super-class-number) number)))
  359.     (if (null sc) "NO_SUPER_CLASS_FOUND" (concat sc no ".h"))))
  360.  
  361. ;; ---------------------- AUX ------------------------
  362.  
  363. (defun user-sign ()
  364.   (car (cdr (assoc (user-login-name) signatures))))
  365.  
  366. (defun cadr (l)
  367.   (car (cdr l)))
  368.  
  369. (defun odd (e)
  370.   "True if it's argument is odd."
  371.   (eq (% e 2) 1))
  372.  
  373. (defun e-empty-line-p ()
  374.   "True if current line is empty."
  375.   (save-excursion
  376.     (beginning-of-line)
  377.     (looking-at "^[ \\t]*$")))
  378.  
  379. (defun insert-right (name diff &optional c)
  380.   (let* ((u  (- objective-C-line-length (length name) diff))
  381.      (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  382.     (insert-char fillChar u)
  383.     (insert name)))
  384.  
  385. (defun insert-centered (name diff &optional c)
  386.   "Inserts the name centered in the Objective-C environment
  387. diff is a number that tells how many positions that already
  388. are used on the line (/*     */ = 4) and the optional c
  389. character is used to fill white space with."
  390.   (let* ((toshare  (- objective-C-line-length (length name) diff))
  391.      (u        (/ toshare 2))
  392.      (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  393.     (insert-char fillChar u)
  394.     (insert name)
  395.     (insert-char fillChar (if (odd toshare) (1+ u) u))))
  396.  
  397. (defun add-user-sign ()
  398.   (interactive)
  399.   (let* ((name (user-login-name))
  400.      (sign (read-string (concat "Signature for " name ": "))))
  401.     (setq signatures (cons (list name sign) signatures))))
  402.  
  403. (defun classes-used ()
  404.   "Extract the used classes from the file"
  405.   (save-excursion
  406.     (let ((aString ""))
  407.       (beginning-of-buffer)
  408.       (re-search-forward "Classes used")
  409.       (forward-line 1)
  410.       (while (e-empty-line-p)
  411.     (forward-line 1))
  412.       (beginning-of-line)
  413.       (while (and
  414.           (not (eobp))
  415.           (not (e-empty-line-p))
  416.           (looking-at "#include"))
  417.     (setq aString (concat aString (grep-class-from-line) " "))
  418.     (forward-line 1)
  419.     (beginning-of-line))
  420.       aString)))
  421.  
  422. (defun beginning-of-line-point (&optional aBool)
  423.   (save-excursion
  424.     (beginning-of-line)
  425.     (cond (aBool (skip-chars-forward " \t*/")))
  426.     (point)))
  427.  
  428. (defun end-of-line-point (&optional aBool)
  429.   (save-excursion
  430.     (end-of-line)
  431.     (cond (aBool (skip-chars-backward " \t*/")))
  432.     (point)))
  433.  
  434. (defun grep-class-from-line ()
  435.   (let ((bp (beginning-of-line-point))
  436.     (ep (end-of-line-point)))
  437.     (buffer-substring (+ bp 9) (- ep 3))))
  438.  
  439. (defun start-of-instance-point ()
  440.   (save-excursion
  441.     (beginning-of-buffer)
  442.     (search-forward "@implementation")
  443.     (forward-line 1)
  444.     (while (or (e-empty-line-p)
  445.            (looking-at "{"))
  446.       (forward-line 1)
  447.       (beginning-of-line))
  448.     (point)))
  449.  
  450. (defun end-of-instance-point ()
  451.   (save-excursion
  452.     (beginning-of-buffer)
  453.     (search-forward "@implementation")
  454.     (search-forward "}")
  455.     (forward-line -1)
  456.     (while (e-empty-line-p)
  457.       (forward-line -1))
  458.     (end-of-line)
  459.     (point)))
  460.  
  461. (defun have-instance-variables ()
  462.   (save-excursion
  463.     (beginning-of-buffer)
  464.     (search-forward "@implementation")
  465.     (forward-line 1)
  466.     (while (e-empty-line-p)      
  467.       (forward-line 1))
  468.     (skip-chars-forward " \t")
  469.     (looking-at "{")))
  470.  
  471. (defun instance-variables ()
  472.   (cond ((have-instance-variables)
  473.      (buffer-substring (start-of-instance-point)
  474.                (end-of-instance-point)))
  475.     (t "\t // none")))
  476.  
  477. (defun start-of-intro-point ()
  478.   (save-excursion
  479.     (beginning-of-buffer)
  480.     (cond ((null (search-forward "Introduction"
  481.                  (start-of-instance-point)
  482.                  t))
  483.        1)
  484.       (t (forward-line 1)
  485.          (while (e-empty-line-p)
  486.            (forward-line 1))
  487.          (beginning-of-line)
  488.          (point)))))
  489.  
  490. (defun end-of-intro-point ()
  491.   (save-excursion
  492.     (beginning-of-buffer)
  493.     (cond ((null (search-forward "Revision History"
  494.                  (start-of-instance-point)
  495.                  t))
  496.        1)
  497.       (t (forward-line -1)
  498.          (while (e-empty-line-p)
  499.            (forward-line -1))
  500.          (end-of-line)
  501.          (point)))))
  502.  
  503. (defun class-intro ()
  504.   (let ((si (start-of-intro-point))
  505.     (ei (end-of-intro-point)))
  506.     (if (or (= si ei) (= si 1) (= ei 1))
  507.     "\tCan't extract the class description since the strings\n\tIntroduction and/or Revision History are missing in the source code."
  508.       (buffer-substring si ei))))
  509.  
  510. (defun find-next-protocol-or-method ()
  511.   (beginning-of-line)
  512.   (while (and (not (eobp))
  513.           (not (looking-at "/\\*====="))
  514.           (not (looking-at "+[a-zA-Z( ]"))
  515.           (not (looking-at "-[a-zA-Z( ]")))
  516.     (forward-line 1)
  517.     (beginning-of-line))
  518.   (cond ((looking-at "/\\*=====")
  519.      (forward-line 1)
  520.      (beginning-of-line)))
  521.   (not (eobp)))
  522.  
  523. (defun line-is-method ()
  524.   (save-excursion
  525.     (beginning-of-line)
  526.     (or (looking-at "+[a-zA-Z( ]")
  527.     (looking-at "-[a-zA-Z( ]"))))
  528.  
  529. (defun line-is-protocol ()
  530.   (save-excursion
  531.     (forward-line -1)
  532.     (beginning-of-line)
  533.     (looking-at "/\\*=====")))
  534.  
  535. (defun is-gps-comment ()
  536.   (save-excursion
  537.     (let ((ordinary (is-ordinary-comment)))
  538.       (beginning-of-line)
  539.       (and (looking-at "---------") ordinary))))
  540.  
  541. (defun is-ordinary-comment ()
  542.   (save-excursion
  543.     (and (char-equal ?* (char-after (- (point) 2)))
  544.      (char-equal ?/ (char-after (- (point) 1)))
  545.      (not (char-equal ?= (char-after (beginning-of-line-point)))))))
  546.  
  547. (defun is-date-entry ()
  548.   (< 50 (- (beginning-of-line-point t) (beginning-of-line-point))))
  549.  
  550. (defun is-method-name-entry ()
  551.   (and (char-equal ?| (char-after (beginning-of-line-point t)))
  552.        (char-equal ?| (char-after (- (end-of-line-point t) 1)))))
  553.  
  554. (defun is-empty-line-info ()
  555.   (string-equal "" (buffer-substring (beginning-of-line-point t)
  556.                      (end-of-line-point))))
  557.  
  558. (defun is-not-crap-line ()
  559.     (and (not (is-date-entry))
  560.      (not (is-method-name-entry))
  561.      (not (is-empty-line-info))))
  562.  
  563. (defun look-for-comment-at-previous-line ()
  564.   (save-excursion
  565.     (forward-line -1)
  566.     (beginning-of-line)
  567.     (skip-chars-forward "\t ")
  568.     (and (char-equal ?/ (char-after (point)))
  569.      (char-equal ?* (char-after (+ (point) 1))))))
  570.  
  571. (defun is-still-comment ()
  572.   (save-excursion
  573.     (beginning-of-line)
  574.     (skip-chars-forward "\t ")
  575.     (if (and (char-equal ?/ (char-after (point)))
  576.          (char-equal ?* (char-after (+ (point) 1))))
  577.     (look-for-comment-at-previous-line)
  578.       t)))
  579.  
  580. (defun is-objc-comment ()
  581.   (save-excursion
  582.     (beginning-of-line)
  583.     (looking-at "//")))
  584.  
  585. (defun gps-comment ()
  586.   (ordinary-comment))
  587.  
  588. (defun ordinary-comment ()
  589.   (let ((aStr ""))
  590.     (forward-line -1)
  591.     (while (is-still-comment)
  592.       (beginning-of-line)
  593.       (skip-chars-forward " \t*/")
  594.       (cond ((is-not-crap-line)
  595.          (setq aStr
  596.            (concat (buffer-substring (point) (end-of-line-point t))
  597.                "\n"
  598.                aStr))))
  599.       (forward-line -1))
  600.     aStr))
  601.  
  602. (defun objc-comment ()
  603.   (let ((aStr ""))
  604.     (while (is-objc-comment)
  605.       (beginning-of-line)
  606.       (skip-chars-forward "/ ")
  607.       (cond ((is-not-crap-line)
  608.          (setq aStr
  609.            (concat (buffer-substring (point) (end-of-line-point t))
  610.                "\n"
  611.                aStr))))
  612.       (forward-line -1))
  613.     aStr))
  614.  
  615. (defun no-comment ()
  616.   "This method has not been documented in the source code.")
  617.  
  618. (defun line-as-doc-file-delimiter ()
  619.   (save-excursion
  620.     (beginning-of-line)
  621.     (skip-chars-forward " \t")
  622.     (setq start (point))
  623.     (end-of-line)
  624.     (skip-chars-backward " \t")
  625.     (concat "\n" (buffer-substring start (point)) "\n")))
  626.  
  627. (defun line-as-inteface-file-delimiter ()
  628.   (save-excursion
  629.     (beginning-of-line)
  630.     (skip-chars-forward " \t")
  631.     (setq start (point))
  632.     (end-of-line)
  633.     (skip-chars-backward " \t")
  634.     (setq name     (buffer-substring start (point)))
  635.     (setq toshare  (- objective-C-line-length (length name) 8))
  636.     (concat "\n/* "
  637.         (make-string (/ toshare 2) ?-)
  638.         " "
  639.         (buffer-substring start (point))
  640.         " "
  641.         (make-string (if (odd toshare)
  642.                  (+ (/ toshare 2) 1)
  643.                (/ toshare 2))
  644.              ?-)
  645.         " */")))
  646.  
  647. (defun skip-comment (str)
  648.   (let ((p (string-match "//" str)))
  649.     (cond ((null p) str)
  650.       (t (substring str 0 p)))))
  651.  
  652. (defun line-as-inteface-file-method ()
  653.   (save-excursion
  654.     (beginning-of-line)
  655.     (skip-chars-forward " \t")
  656.     (setq start (point))
  657.     (re-search-forward "{")
  658.     (backward-char 1)
  659.     (skip-chars-backward " \t\n")
  660.     (concat (skip-comment (buffer-substring start (point))) ";")))
  661.  
  662. (defun extract-method-comment ()
  663.   (forward-line -1)
  664.   (while (e-empty-line-p)
  665.     (forward-line -1))
  666.   (end-of-line)
  667.   (skip-chars-backward " \t")
  668.   (cond ((is-gps-comment)      (gps-comment))
  669.     ((is-ordinary-comment) (ordinary-comment))
  670.     ((is-objc-comment)     (objc-comment))
  671.     (t                     (no-comment))))
  672.  
  673. (defun method-description (method-name start-point)
  674.   (save-excursion
  675.     (goto-char start-point)
  676.     (concat method-name "\n" (extract-method-comment))))
  677.  
  678. (defun line-as-doc-file-method ()
  679.   (save-excursion
  680.     (beginning-of-line)
  681.     (skip-chars-forward " \t")
  682.     (setq start (point))
  683.     (re-search-forward "{")
  684.     (backward-char 1)
  685.     (skip-chars-backward " \t\n")
  686.     (method-description
  687.      (concat "|" (buffer-substring start (point)) "|") start)))
  688.  
  689. (defun class-as-short ()
  690.   (save-excursion
  691.     (let ((aString ""))
  692.       (beginning-of-buffer)
  693.       (re-search-forward "@implementation")
  694.       (while (and (not (eobp)) (find-next-protocol-or-method))
  695.     (setq aString
  696.           (concat
  697.            aString
  698.            (cond ((line-is-protocol) (line-as-doc-file-delimiter))
  699.              ((line-is-method)   (line-as-doc-file-method))
  700.              (t ""))
  701.            "\n"))
  702.     (forward-line))
  703.       aString)))
  704.  
  705. (defun class-as-short-no-comments ()
  706.   (save-excursion
  707.     (let ((aString ""))
  708.       (beginning-of-buffer)
  709.       (re-search-forward "@implementation")
  710.       (while (and (not (eobp)) (find-next-protocol-or-method))
  711.     (setq aString
  712.           (concat
  713.            aString
  714.            (cond ((line-is-protocol) (line-as-inteface-file-delimiter))
  715.              ((line-is-method)   (line-as-inteface-file-method))
  716.              (t ""))
  717.            "\n"))
  718.     (forward-line))
  719.       aString)))
  720.  
  721. ;; ------------------ Objective-C mode -------------------
  722.  
  723. (defun describe-objective-C-mode ()
  724.   (interactive)
  725.   (describe-mode))
  726.  
  727. (defun objective-C-mfile-header ()
  728.   "Build a class skeleton prompting for class name."
  729.   (interactive)
  730.   (if (not (is-m-file))
  731.       (message "This is not an implementation file (.m)!")
  732.     (let* ((file  (m-filename))
  733.        (class (class-from-filename))
  734.        (nr    (number-from-filename))
  735.        (cname (read-string "Class: " class))
  736.        (super (read-string "Super: " "Object")))
  737.       (if (not (e-empty-line-p))
  738.       (progn (end-of-line)(newline)))
  739.       (indent-to 0)                
  740.       (let ((textstart (point)))
  741.     (insert "/* ")
  742.     (insert-char ?- (- objective-C-line-length 3))
  743.     (insert "\n\n")
  744.     (insert "\tProject: \n\n")
  745.     (insert "\tObjective-C source file for the class " cname "\n\n")
  746.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  747.         ", " (user-full-name) "\n")
  748.     (insert "\tALL RIGHTS RESERVED.\n\n")
  749.     (insert "\tDate:\t\t\t\tRev:\n")
  750.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  751.     (insert-centered cname 0)
  752.     (insert "\n\n")
  753.     (insert "\t1. Introduction")
  754.     (insert "\n\n\n")
  755.     (insert "\t2. Revision History")
  756.     (insert "\n\n")
  757.     (insert "\t___\tThe starting point.\n")
  758.     (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  759.     (insert "\t3. Source Code")
  760.     (insert "\n\n")
  761.     (insert-char ?- (- objective-C-line-length 3))
  762.     (insert " */\n\n")
  763.     (comment-line "Include files")
  764.     (insert "#include <pm/pm.h>\n#include <db/db.h>\n\n")
  765.     (comment-line " Classes used ")
  766.     (insert "\n\n")
  767.     (comment-line " Externals ")
  768.     (insert "\n\n")
  769.     (comment-line " Defines ")
  770.     (insert "\n\n")
  771.     (comment-line " Class variables ")
  772.     (insert "\n\n")
  773.     (comment-box (concat "Implementation of class " cname))
  774.     (insert "#include \"" (concat (substring file 0 -1) "h") "\"\n\n")
  775.     (insert "@implementation " cname " : " super"\n{\n\n}\n\n")
  776.     (comment-box "Initialize")
  777.     (insert "\n\n")
  778.     (comment-box "Free")
  779.     (insert "\n\n")
  780.     (comment-box "Methods for access to Instance Variables")
  781.     (insert "\n\n")
  782.     (comment-box "Public methods")
  783.     (insert "\n\n")
  784.     (comment-box "Private methods")
  785.     (insert "\n\n")
  786.     (comment-box "Archiving methods")
  787.     (insert "\n\n")
  788.     (insert "@end\n")
  789.     (cond (window-system
  790.            (hilit-highlight-region textstart (point))))))
  791.     (re-search-backward "@implementation")
  792.     (next-line 2)
  793.     (objective-C-indent-line)))
  794.  
  795. (defun objective-C-hfile-header (&optional classname super-filename)
  796.   "Gives an interface file sceleton."
  797.   (interactive)
  798.   (if (not (is-h-file))
  799.       (message "This is not an interface file (.h)!")
  800.     (let* ((class (if (null classname) (class-from-filename) classname))
  801.        (cname (read-string "Class: " class))
  802.        (nr    (number-from-filename))
  803.        (super (if (null super-filename)
  804.               (concat (read-string "Super: ") ".h")
  805.             super-filename)))
  806.       (let ((textstart (point)))
  807.     (insert "/* ")
  808.     (insert-char ?- (- objective-C-line-length 3))
  809.     (insert "\n\n")
  810.     (insert "\tProject: \n\n")
  811.     (insert "\tObjective-C interface file for the class " cname "\n\n")
  812.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  813.         ", " (user-full-name) "\n")
  814.     (insert "\tALL RIGHTS RESERVED.\n\n")
  815.     (insert "\tDate:\t\t\t\tRev:\n")
  816.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  817.     (insert " */\n\n")
  818.     (comment-box (concat "Interface of class " cname))
  819.     (insert "#include \"" super "\"\n\n")
  820.     (insert "@interface " cname " : " (class-from-filename super)
  821.         "\n{\n\n}\n\n")
  822.     (insert "@end\n")
  823.     (cond (window-system
  824.            (hilit-highlight-region textstart (point))))))
  825.     (re-search-backward "@interface")
  826.     (next-line 2)
  827.     (objective-C-indent-line)))
  828.  
  829. (defun generate-Objective-C-hfile ()
  830.   "Generate the interface file for the current implementation file."
  831.   (interactive)
  832.   (let* ((file-name (read-string "Interface file name: "
  833.                  (concat (h-file-dir) (h-filename))))
  834.      (buf       (create-file-buffer file-name))
  835.      (class     (class-from-filename))
  836.      (no        (number-from-filename))
  837.      (instance  (instance-variables))
  838.      (short     (class-as-short-no-comments))
  839.      (super     (super-hfilename)))
  840.     (set-buffer buf)
  841.     (objective-C-mode)
  842.     (set-visited-file-name file-name)
  843.     (let ((textstart (point))) 
  844.       (insert "/* ")
  845.       (insert-char ?- (- objective-C-line-length 3))
  846.       (insert "\n\n")
  847.       (insert "\tProject: \n\n")
  848.       (insert "\tObjective-C interface file for the class " class "\n\n")
  849.       (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  850.         ", " (user-full-name) "\n")
  851.       (insert "\tALL RIGHTS RESERVED.\n\n")
  852.       (insert "\tDate:\t\t\t\tRev:\n")
  853.       (insert "\t" (eb-date)    "\t\t\t___\n\n")
  854.       (insert " */\n\n")
  855.       (insert "#ifndef _" (upcase class) "_H_\n")
  856.       (insert "#define _" (upcase class) "_H_\n\n")
  857.       (comment-box (concat "Interface of class " class))
  858.       (if (string-equal "Object.h" super)
  859.       (insert "#include <objc/Object.h>\n\n")
  860.     (insert "#include \"" super "\"\n\n"))
  861.       (insert "@interface " class " : " (class-from-filename super) "\n{\n")
  862.       (insert instance)
  863.       (insert "\n}\n")
  864.       (insert short)
  865.       (insert "\n@end\n")
  866.       (insert "#endif\n\n")
  867.       (cond (window-system
  868.          (hilit-highlight-region textstart (point)))))
  869.     (beginning-of-buffer)
  870.     (display-buffer buf)))
  871.  
  872. (defun generate-Objective-C-documentation ()
  873.   "Open a new buffer and write the documentation there."
  874.   (interactive)
  875.   (let* ((file-name (read-string "Documentation file name: "
  876.                  (concat (doc-dir) (doc-filename))))
  877.      (buf       (create-file-buffer file-name))
  878.      (used      (classes-used))
  879.      (class     (class-from-filename))
  880.      (super     (super-class))
  881.      (no        (number-from-filename))
  882.      (instance  (instance-variables))
  883.      (short     (class-as-short))
  884.      (intro     (class-intro)))
  885.     (set-buffer buf)
  886.     (set-visited-file-name file-name)
  887.     (indent-to 0)                
  888.     (insert-char ?- objective-C-line-length)
  889.     (insert "\n\n")
  890.     (insert "\tProject: \n\n")
  891.     (insert "\tObjective-C documentation file for the class "
  892.         class "\n")
  893.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  894.         ", " (user-full-name) "\n")
  895.     (insert "\tDate:\t\t\t\tRev:\n")
  896.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  897.     (insert "\n\n\n")
  898.     (insert-centered class 0)
  899.     (insert "\n\n\n\tInherits from:\t\t" super "\n\n")
  900.     (insert "\tClasses used:\t\t" used "\n\n")
  901.     (insert "\tInterface file:\t\t" class "." no ".h" "\n\n")
  902.     (insert "\tImplementation file:\t" class "." no ".m" "\n\n\n")
  903.     (insert-centered "Introduction" 0)
  904.     (insert "\n\n")
  905.     (insert intro)
  906.     (insert "\n\n")
  907.     (insert-centered "Instance Variables" 0)
  908.     (insert "\n\n")
  909.     (insert instance)
  910.     (insert "\n\n")
  911.     (insert-centered "Methods" 0)
  912.     (insert "\n")
  913.     (insert short)   
  914.     (insert "\nEnd\n")
  915.     (beginning-of-buffer)
  916.     (display-buffer buf)))
  917.  
  918. (defun comment-box (name)
  919.   "Print name in an comment-box"
  920.   (if (not (e-empty-line-p))
  921.       (progn (end-of-line)(newline)))
  922.   (insert "/*")
  923.   (insert-centered "" 2 ?=)
  924.   (insert "\n")
  925.   (insert-centered name 0 (string-to-char " "))
  926.   (insert "\n")
  927.   (insert-centered "" 2 ?=)
  928.   (insert "*/\n"))
  929.  
  930. (defun comment-line (name)
  931.   "Print name in an comment-line"
  932.   (if (not (e-empty-line-p))
  933.       (progn (end-of-line)(newline)))
  934.   (insert "/* ")
  935.   (insert-centered (concat " " name " ") 6 ?-)
  936.   (insert " */\n"))
  937.  
  938. (defun objective-C-protocol ()
  939.   "Build a protocol skeleton prompting for protocol name."
  940.   (interactive)
  941.   (comment-box (read-string "Protocol name: ")))
  942.  
  943. (defun objective-C-codelimit ()
  944.   "Print name on a centered line."
  945.   (interactive)
  946.   (comment-line (read-string "Centered text: ")))
  947.  
  948. (defun objective-C-method (prefix name)
  949.   (indent-to 0)                
  950.   (let ((textstart (point))) 
  951.     (insert "/*")
  952.     (insert-centered "" 2 ?-)
  953.     (insert "\n")
  954.     (insert "|" prefix name "| \n" (if (string-equal "-" prefix)
  955.                        "\nReturn self.\n"
  956.                      "\n"))
  957.     (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  958.     (insert "\n")
  959.     (insert-centered "" 2 ?-)
  960.     (insert "*/\n")
  961.     (insert prefix name "\n")
  962.     (insert "{\n")
  963.     (indent-to objective-C-indent-level)
  964.     (if (string-equal "+" prefix)
  965.     (insert "self = [super new];\n")
  966.       (insert "\n"))
  967.     (indent-to objective-C-indent-level)
  968.     (insert "return self;\n")
  969.     (insert "}\n\n")
  970.     (cond (window-system
  971.        (hilit-highlight-region textstart (point)))))
  972.   (next-line -4))
  973.  
  974. (defun objective-C-method-comment ()
  975.   "Insert a comment according to the style used with methods in GPS"
  976.   (interactive)
  977.   (indent-to 0)                
  978.   (let ((textstart (point)))
  979.     (insert "/*")
  980.     (insert-centered "" 2 ?-)
  981.     (insert "\n\n\n")
  982.     (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  983.     (insert "\n")
  984.     (insert-centered "" 2 ?-)
  985.     (insert "*/\n")
  986.     (cond (window-system
  987.        (hilit-highlight-region textstart (point))))))
  988.  
  989. (defun objective-C-instance-method ()
  990.   "Build a routine skeleton prompting for method name."
  991.   (interactive)
  992.   (if (not (e-empty-line-p))
  993.       (progn (end-of-line)(newline)))
  994.   (objective-C-method "-" (read-string "Instance method name: ")))
  995.  
  996. (defun objective-C-factory-method ()
  997.   "Build a routine skeleton prompting for method name."
  998.   (interactive)
  999.   (if (not (e-empty-line-p))
  1000.       (progn (end-of-line)(newline)))
  1001.   (objective-C-method "+" (read-string "Factory method name: ")))
  1002.  
  1003. ;; ------------------ C- mode fix ---------------------
  1004.  
  1005. ;; This is used by indent-for-comment
  1006. ;; to decide how much to indent a comment in C code
  1007. ;; based on its context.
  1008. (defun objective-C-comment-indent ()
  1009.   (if (looking-at "^/\\*")
  1010.       0                ;Existing comment at bol stays there.
  1011.     (save-excursion
  1012.       (skip-chars-backward " \t")
  1013.       (max (1+ (current-column))    ;Else indent at comment column
  1014.        comment-column))))    ; except leave at least one space.
  1015.  
  1016. ;; implement this function later
  1017. (defun electric-objective-C-keyword-match ()
  1018.   "Match two following lines with keyword arguments"
  1019.   (interactive)
  1020.   (insert ":"))
  1021.  
  1022. (defun electric-objective-C-brace (arg)
  1023.   "Insert character and correct line's indentation."
  1024.   (interactive "P")
  1025.   (let (insertpos)
  1026.     (if (and (not arg)
  1027.          (eolp)
  1028.          (or (save-excursion
  1029.            (skip-chars-backward " \t")
  1030.            (bolp))
  1031.          (if objective-C-auto-newline
  1032.              (progn (objective-C-indent-line) (newline) t) nil)))
  1033.     (progn
  1034.       (insert last-command-char)
  1035.       (objective-C-indent-line)
  1036.       (if objective-C-auto-newline
  1037.           (progn
  1038.         (setq insertpos (1- (point)))
  1039.         (newline)
  1040.         (objective-C-indent-line)))
  1041.       (save-excursion
  1042.         (if insertpos (goto-char (1+ insertpos)))
  1043.         (delete-char -1))))
  1044.     (if insertpos
  1045.     (save-excursion
  1046.       (goto-char insertpos)
  1047.       (self-insert-command (prefix-numeric-value arg)))
  1048.       (self-insert-command (prefix-numeric-value arg)))))
  1049.  
  1050. (defun electric-objective-C-semi (arg)
  1051.   "Insert character and correct line's indentation."
  1052.   (interactive "P")
  1053.   (if objective-C-auto-newline
  1054.       (electric-objective-C-terminator arg)
  1055.     (self-insert-command (prefix-numeric-value arg))))
  1056.  
  1057. (defun electric-objective-C-terminator (arg)
  1058.   "Insert character and correct line's indentation."
  1059.   (interactive "P")
  1060.   (let (insertpos (end (point)))
  1061.     (if (and (not arg) (eolp)
  1062.          (not (save-excursion
  1063.             (beginning-of-line)
  1064.             (skip-chars-forward " \t")
  1065.             (or (= (following-char) ?#)
  1066.             ;; Colon is special only after a label, or case ....
  1067.             ;; So quickly rule out most other uses of colon
  1068.             ;; and do no indentation for them.
  1069.             (and (eq last-command-char ?:)
  1070.                  (not (looking-at "case"))
  1071.                  (save-excursion
  1072.                    (forward-word 2)
  1073.                    (<= (point) end)))
  1074.             (progn
  1075.               (beginning-of-defun)
  1076.               (let ((pps (parse-partial-sexp (point) end)))
  1077.                 (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
  1078.     (progn
  1079.       (insert last-command-char)
  1080.       (objective-C-indent-line)
  1081.       (and objective-C-auto-newline
  1082.            (not (objective-C-inside-parens-p))
  1083.            (progn
  1084.          (setq insertpos (1- (point)))
  1085.          (newline)
  1086.          (objective-C-indent-line)))
  1087.       (save-excursion
  1088.         (if insertpos (goto-char (1+ insertpos)))
  1089.         (delete-char -1))))
  1090.     (if insertpos
  1091.     (save-excursion
  1092.       (goto-char insertpos)
  1093.       (self-insert-command (prefix-numeric-value arg)))
  1094.       (self-insert-command (prefix-numeric-value arg)))))
  1095.  
  1096. (defun objective-C-inside-parens-p ()
  1097.   (condition-case ()
  1098.       (save-excursion
  1099.     (save-restriction
  1100.       (narrow-to-region (point)
  1101.                 (progn (beginning-of-defun) (point)))
  1102.       (goto-char (point-max))
  1103.       (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
  1104.     (error nil)))
  1105.  
  1106. (defun objective-C-indent-command (&optional whole-exp)
  1107.   (interactive "P")
  1108.   "Indent current line as C code, or in some cases insert a tab character.
  1109. If objective-C-tab-always-indent is non-nil (the default), always indent current line.
  1110. Otherwise, indent the current line only if point is at the left margin
  1111. or in the line's indentation; otherwise insert a tab.
  1112.  
  1113. A numeric argument, regardless of its value,
  1114. means indent rigidly all the lines of the expression starting after point
  1115. so that this line becomes properly indented.
  1116. The relative indentation among the lines of the expression are preserved."
  1117.   (if whole-exp
  1118.       ;; If arg, always indent this line as C
  1119.       ;; and shift remaining lines of expression the same amount.
  1120.       (let ((shift-amt (objective-C-indent-line))
  1121.         beg end)
  1122.     (save-excursion
  1123.       (if objective-C-tab-always-indent
  1124.           (beginning-of-line))
  1125.       (setq beg (point))
  1126.       (forward-sexp 1)
  1127.       (setq end (point))
  1128.       (goto-char beg)
  1129.       (forward-line 1)
  1130.       (setq beg (point)))
  1131.     (if (> end beg)
  1132.         (indent-code-rigidly beg end shift-amt "#")))
  1133.     (if (and (not objective-C-tab-always-indent)
  1134.          (save-excursion
  1135.            (skip-chars-backward " \t")
  1136.            (not (bolp))))
  1137.     (insert-tab)
  1138.       (objective-C-indent-line))))
  1139.  
  1140. (defun objective-C-indent-line ()
  1141.   "Indent current line as C code.
  1142. Return the amount the indentation changed by."
  1143.   (let ((indent (calculate-objective-C-indent nil))
  1144.     beg shift-amt
  1145.     (case-fold-search nil)
  1146.     (pos (- (point-max) (point))))
  1147.     (beginning-of-line)
  1148.     (setq beg (point))
  1149.     (cond ((eq indent nil)
  1150.        (setq indent (current-indentation)))
  1151.       ((eq indent t)
  1152.        (setq indent (calculate-objective-C-indent-within-comment)))
  1153.       ((looking-at "[ \t]*#")
  1154.        (setq indent 0))
  1155.       (t
  1156.        (skip-chars-forward " \t")
  1157.        (if (listp indent) (setq indent (car indent)))
  1158.        (cond ((or (looking-at "case\\b")
  1159.               (and (looking-at "[A-Za-z]")
  1160.                (save-excursion
  1161.                  (forward-sexp 1)
  1162.                  (looking-at ":"))))
  1163.           (setq indent (max 1 (+ indent objective-C-label-offset))))
  1164.          ((and (looking-at "else\\b")
  1165.                (not (looking-at "else\\s_")))
  1166.           (setq indent (save-excursion
  1167.                  (objective-C-backward-to-start-of-if)
  1168.                  (current-indentation))))
  1169.          ((= (following-char) ?})
  1170.           (setq indent (- indent objective-C-indent-level)))
  1171.          ((= (following-char) ?{)
  1172.           (setq indent (+ indent objective-C-brace-offset))))))
  1173.     (skip-chars-forward " \t")
  1174.     (setq shift-amt (- indent (current-column)))
  1175.     (if (zerop shift-amt)
  1176.     (if (> (- (point-max) pos) (point))
  1177.         (goto-char (- (point-max) pos)))
  1178.       (delete-region beg (point))
  1179.       (indent-to indent)
  1180.       ;; If initial point was within line's indentation,
  1181.       ;; position after the indentation.  Else stay at same point in text.
  1182.       (if (> (- (point-max) pos) (point))
  1183.       (goto-char (- (point-max) pos))))
  1184.     shift-amt))
  1185.  
  1186. (defun calculate-objective-C-indent (&optional parse-start)
  1187.   "Return appropriate indentation for current line as C code.
  1188. In usual case returns an integer: the column to indent to.
  1189. Returns nil if line starts inside a string, t if in a comment."
  1190.   (save-excursion
  1191.     (beginning-of-line)
  1192.     (let ((indent-point (point))
  1193.       (case-fold-search nil)
  1194.       state
  1195.       containing-sexp)
  1196.       (if parse-start
  1197.       (goto-char parse-start)
  1198.     (beginning-of-defun))
  1199.       (while (< (point) indent-point)
  1200.     (setq parse-start (point))
  1201.     (setq state (parse-partial-sexp (point) indent-point 0))
  1202.     (setq containing-sexp (car (cdr state))))
  1203.       (cond ((or (nth 3 state) (nth 4 state))
  1204.          ;; return nil or t if should not change this line
  1205.          (nth 4 state))
  1206.         ((null containing-sexp)
  1207.          ;; Line is at top level.  May be data or function definition,
  1208.          ;; or may be function argument declaration.
  1209.          ;; Indent like the previous top level line
  1210.          ;; unless that ends in a closeparen without semicolon,
  1211.          ;; in which case this line is the first argument decl.
  1212.          (goto-char indent-point)
  1213.          (skip-chars-forward " \t")
  1214.          (if (= (following-char) ?{)
  1215.          0   ; Unless it starts a function body
  1216.            (objective-C-backward-to-noncomment (or parse-start (point-min)))
  1217.            ;; Look at previous line that's at column 0
  1218.            ;; to determine whether we are in top-level decls
  1219.            ;; or function's arg decls.  Set basic-indent accordinglu.
  1220.            (let ((basic-indent
  1221.               (save-excursion
  1222.             (re-search-backward "^[^ \^L\t\n#]" nil 'move)
  1223.             (if (and (looking-at "\\sw\\|\\s_")
  1224.                  (looking-at ".*(")
  1225.                  (progn
  1226.                    (goto-char (1- (match-end 0)))
  1227.                    (forward-sexp 1)
  1228.                    (and (< (point) indent-point)
  1229.                     (not (memq (following-char)
  1230.                            '(?\, ?\;))))))
  1231.                 objective-C-argdecl-indent 0))))
  1232.         
  1233.            ;; Now add a little if this is a continuation line.
  1234.            (+ basic-indent
  1235.             (if    (or (bobp)
  1236.                 (memq (preceding-char) '(?\) ?\; ?\})))
  1237.             0 0)))))
  1238.           ((/= (char-after containing-sexp) ?{)
  1239.            ;; line is expression, not statement:
  1240.            ;; indent to just after the surrounding open.
  1241.         
  1242.          (goto-char (1+ containing-sexp))
  1243.          (current-column))
  1244.         (t
  1245.          ;; Statement level.  Is it a continuation or a new statement?
  1246.          ;; Find previous non-comment character.
  1247.          (goto-char indent-point)
  1248.          (objective-C-backward-to-noncomment containing-sexp)
  1249.          ;; Back up over label lines, since they don't
  1250.          ;; affect whether our line is a continuation.
  1251.          (while (or (eq (preceding-char) ?\,)
  1252.             (and (eq (preceding-char) ?:)
  1253.                  (or (eq (char-after (- (point) 2)) ?\')
  1254.                  (memq (char-syntax (char-after (- (point) 2)))
  1255.                        '(?w ?_)))))
  1256.            (if (eq (preceding-char) ?\,)
  1257.            (objective-C-backward-to-start-of-continued-exp containing-sexp))
  1258.            (beginning-of-line)
  1259.            (objective-C-backward-to-noncomment containing-sexp))
  1260.          ;; Now we get the answer.
  1261.          (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?\{)))
  1262.          ;; This line is continuation of preceding line's statement;
  1263.          ;; indent  objective-C-continued-statement-offset  more than the
  1264.          ;; previous line of the statement.
  1265.          (progn
  1266.            (objective-C-backward-to-start-of-continued-exp containing-sexp)
  1267.            (+ objective-C-continued-statement-offset (current-column)))
  1268.            ;; This line starts a new statement.
  1269.            ;; Position following last unclosed open.
  1270.            (goto-char containing-sexp)
  1271.            ;; Is line first statement after an open-brace?
  1272.            (or
  1273.         ;; If no, find that first statement and indent like it.
  1274.         (save-excursion
  1275.           (forward-char 1)
  1276.           (let ((colon-line-end 0))
  1277.             (while (progn (skip-chars-forward " \t\n")
  1278.                   (looking-at "#\\|/\\*\\|case[ \t\n].*:\\|[a-zA-Z0-9_$]*:"))
  1279.               ;; Skip over comments and labels following openbrace.
  1280.               (cond ((= (following-char) ?\#)
  1281.                  (forward-line 1))
  1282.                 ((= (following-char) ?\/)
  1283.                  (forward-char 2)
  1284.                  (search-forward "*/" nil 'move))
  1285.                 ;; case or label:
  1286.                 (t
  1287.                  (save-excursion (end-of-line)
  1288.                          (setq colon-line-end (point)))
  1289.                  (search-forward ":"))))
  1290.             ;; The first following code counts
  1291.             ;; if it is before the line we want to indent.
  1292.             (and (< (point) indent-point)
  1293.              (if (> colon-line-end (point))
  1294.                  (- (current-indentation) objective-C-label-offset)
  1295.                (current-column)))))
  1296.         ;; If no previous statement,
  1297.         ;; indent it relative to line brace is on.
  1298.         ;; For open brace in column zero, don't let statement
  1299.         ;; start there too.  If objective-C-indent-offset is zero,
  1300.         ;; use objective-C-brace-offset + objective-C-continued-statement-offset instead.
  1301.         ;; For open-braces not the first thing in a line,
  1302.         ;; add in objective-C-brace-imaginary-offset.
  1303.         (+ (if (and (bolp) (zerop objective-C-indent-level))
  1304.                (+ objective-C-brace-offset objective-C-continued-statement-offset)
  1305.              objective-C-indent-level)
  1306.            ;; Move back over whitespace before the openbrace.
  1307.            ;; If openbrace is not first nonwhite thing on the line,
  1308.            ;; add the objective-C-brace-imaginary-offset.
  1309.            (progn (skip-chars-backward " \t")
  1310.               (if (bolp) 0 objective-C-brace-imaginary-offset))
  1311.            ;; If the openbrace is preceded by a parenthesized exp,
  1312.            ;; move to the beginning of that;
  1313.            ;; possibly a different line
  1314.            (progn
  1315.              (if (eq (preceding-char) ?\))
  1316.              (forward-sexp -1))
  1317.              ;; Get initial indentation of the line we are on.
  1318.              (current-indentation))))))))))
  1319.  
  1320. (defun calculate-objective-C-indent-within-comment ()
  1321.   "Return the indentation amount for line, assuming that
  1322. the current line is to be regarded as part of a block comment."
  1323.   (let (end star-start)
  1324.     (save-excursion
  1325.       (beginning-of-line)
  1326.       (skip-chars-forward " \t")
  1327.       (setq star-start (= (following-char) ?\*))
  1328.       (skip-chars-backward " \t\n")
  1329.       (setq end (point))
  1330.       (beginning-of-line)
  1331.       (skip-chars-forward " \t")
  1332.       (and (re-search-forward "/\\*[ \t]*" end t)
  1333.        star-start
  1334.        (goto-char (1+ (match-beginning 0))))
  1335.       (current-column))))
  1336.  
  1337.  
  1338. (defun objective-C-backward-to-noncomment (lim)
  1339.   (let (opoint stop)
  1340.     (while (not stop)
  1341.       (skip-chars-backward " \t\n\f" lim)
  1342.       (setq opoint (point))
  1343.       (if (and (>= (point) (+ 2 lim))
  1344.            (save-excursion
  1345.          (forward-char -2)
  1346.          (looking-at "\\*/")))
  1347.       (search-backward "/*" lim 'move)
  1348.     (beginning-of-line)
  1349.     (skip-chars-forward " \t")
  1350.     (if (looking-at "#")
  1351.         (setq stop (<= (point) lim))
  1352.       (setq stop t)
  1353.       (goto-char opoint))))))
  1354.  
  1355. (defun objective-C-backward-to-start-of-continued-exp (lim)
  1356.   (if (= (preceding-char) ?\))
  1357.       (forward-sexp -1))
  1358.   (beginning-of-line)
  1359.   (if (<= (point) lim)
  1360.       (goto-char (1+ lim)))
  1361.   (skip-chars-forward " \t"))
  1362.  
  1363. (defun objective-C-backward-to-start-of-if (&optional limit)
  1364.   "Move to the start of the last ``unbalanced'' if."
  1365.   (or limit (setq limit (save-excursion (beginning-of-defun) (point))))
  1366.   (let ((if-level 1)
  1367.     (case-fold-search nil))
  1368.     (while (not (zerop if-level))
  1369.       (backward-sexp 1)
  1370.       (cond ((looking-at "else\\b")
  1371.          (setq if-level (1+ if-level)))
  1372.         ((looking-at "if\\b")
  1373.          (setq if-level (1- if-level)))
  1374.         ((< (point) limit)
  1375.          (setq if-level 0)
  1376.          (goto-char limit))))))
  1377.  
  1378. (defun mark-objective-C-function ()
  1379.   "Put mark at end of C function, point at beginning."
  1380.   (interactive)
  1381.   (push-mark (point))
  1382.   (end-of-defun)
  1383.   (push-mark (point))
  1384.   (beginning-of-defun)
  1385.   (backward-paragraph))
  1386.  
  1387.  
  1388.  
  1389. /* End of text from cm-next-9:next */
  1390.